﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.ServiceModel;
using System.ServiceModel.Syndication;
namespace AzureReader.BLL
{
    /// <summary>
    /// Creates formatters for RSS 2.0 and Atom 1.0 according to the input content.
    /// </summary>
    /// <copyright>Daniel Cazzulino: http://www.clariusconsulting.net/blogs/kzu</copyright>
    public static class SyndicationFormatterFactory
    {
        static XmlReaderSettings settings;

        static SyndicationFormatterFactory()
        {
            // Makes the processing faster for the readers we create.
            settings = new XmlReaderSettings();
            settings.IgnoreComments = true;
            settings.IgnoreProcessingInstructions = true;
            settings.IgnoreWhitespace = true;
            settings.CheckCharacters = true;
            settings.CloseInput = true;
        }

        /// <summary>
        /// Creates a <see cref="SyndicationFeedFormatter"/> according to the 
        /// input format.
        /// </summary>
        /// <param name="uriString">Feed location</param>
        /// <exception cref="NotSupportedException">The input does not contain a valid RSS 2.0 or Atom 1.0 feed.</exception>
        public static SyndicationFeedFormatter CreateFeedFormatter(string uriString)
        {
            using (XmlReader reader = XmlReader.Create(uriString, settings))
                return CreateFeedFormatter(reader);
        }

        /// <summary>
        /// Creates a <see cref="SyndicationFeedFormatter"/> according to the 
        /// input format.
        /// </summary>
        /// <param name="uri">Feed location</param>
        /// <exception cref="NotSupportedException">The input does not contain a valid RSS 2.0 or Atom 1.0 feed.</exception>
        public static SyndicationFeedFormatter CreateFeedFormatter(Uri uri)
        {
            using (XmlReader reader = XmlReader.Create(uri.ToString(), settings))
                return CreateFeedFormatter(reader);
        }

        /// <summary>
        /// Creates a <see cref="SyndicationFeedFormatter"/> according to the 
        /// input format.
        /// </summary>
        /// <param name="reader">Feed source</param>
        /// <exception cref="NotSupportedException">The input does not contain a valid RSS 2.0 or Atom 1.0 feed.</exception>
        public static SyndicationFeedFormatter CreateFeedFormatter(XmlReader reader)
        {
            if (reader.ReadState == ReadState.Initial)
            {
                reader.MoveToContent();
            }

            Rss20FeedFormatter rss = new Rss20FeedFormatter();
            if (rss.CanRead(reader))
            {
                return rss;
            }

            Atom10FeedFormatter atom = new Atom10FeedFormatter();
            if (atom.CanRead(reader))
            {
                return atom;
            }

            throw new NotSupportedException("Invalid feed root element: " + reader.Name);
        }

        /// <summary>
        /// Creates a <see cref="SyndicationItemFormatter"/> according to the 
        /// input format.
        /// </summary>
        /// <param name="uriString">Item location</param>
        /// <exception cref="NotSupportedException">The input does not contain a valid RSS 2.0 or Atom 1.0 item.</exception>
        public static SyndicationItemFormatter CreateItemFormatter(string uriString)
        {
            using (XmlReader reader = XmlReader.Create(uriString, settings))
                return CreateItemFormatter(reader);
        }

        /// <summary>
        /// Creates a <see cref="SyndicationItemFormatter"/> according to the 
        /// input format.
        /// </summary>
        /// <param name="uri">Item location</param>
        /// <exception cref="NotSupportedException">The input does not contain a valid RSS 2.0 or Atom 1.0 item.</exception>
        public static SyndicationItemFormatter CreateItemFormatter(Uri uri)
        {
            using (XmlReader reader = XmlReader.Create(uri.ToString(), settings))
                return CreateItemFormatter(reader);
        }

        /// <summary>
        /// Creates a <see cref="SyndicationItemFormatter"/> according to the 
        /// input format.
        /// </summary>
        /// <param name="reader">Item source</param>
        /// <exception cref="NotSupportedException">The input does not contain a valid RSS 2.0 or Atom 1.0 item.</exception>
        public static SyndicationItemFormatter CreateItemFormatter(XmlReader reader)
        {
            if (reader.ReadState == ReadState.Initial)
            {
                reader.MoveToContent();
            }

            Rss20ItemFormatter rss = new Rss20ItemFormatter();
            if (rss.CanRead(reader))
            {
                return rss;
            }

            Atom10ItemFormatter atom = new Atom10ItemFormatter();
            if (atom.CanRead(reader))
            {
                return atom;
            }

            throw new NotSupportedException("Invalid item element: " + reader.Name);
        }
    }


}
